﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace B121B {
    /// <summary>
    /// Creates vehicles and sellers
    /// </summary>
    public class VehicleSellerCreator {
        private string[] Brands = new string[] { "BMW", "Mercedes", "Toyota", "Porsche" };
        private string[] Models = new string[] { "Z4", "CLS", "Avensis", "911" };
        private bool[] TrueOrFalse = new bool[] { true, false };

        private string[] SellerNames = new string[] { "Knud", "Erik & Co.", "Palle", "Co & Co.", "Far & Søn", "Søn & Søn" };

        /// <summary>
        /// Creates vehicles and sellers, assigns them to a VehicleCollection and each other
        /// </summary>
        /// <param name="vhc">VehicleCollection to add the vehicles and sellers to</param>
        /// <param name="nSellers">Number of sellers to create</param>
        /// <param name="nVehicles">Number of vehicles to create</param>
        public void CreateVehiclesAndSellers(VehicleCollection vhc, int nSellers, int nVehicles) {
            Random rand = new Random(17); // Create the same vehicles every time

            CreateSellers(vhc, nSellers, rand);

            CreateVehiclesAndSellers(vhc, nVehicles, rand);

            AssignVehiclesAndSellersToEachOther(vhc, rand);
        }

        /// <summary>
        /// Assigns vehicles and sellers to each other
        /// </summary>
        /// <param name="vhc">VehicleCollection from which to assign vehicles and sellers to each other</param>
        /// <param name="rand">Random to use</param>
        private static void AssignVehiclesAndSellersToEachOther(VehicleCollection vhc, Random rand) {
            foreach (Vehicle v in vhc.GetVehicles()) { // Assign each vehicle to a seller, and that seller to that vehicle
                Seller s = vhc.Sellers[rand.Next(0, vhc.Sellers.Count)];
                v.Seller = s;
                s.VehiclesForSale.Add(v);
            }
        }

        /// <summary>
        /// Creates a set of vehicles
        /// </summary>
        /// <param name="vhc">VehicleCollection to add the vehicles to</param>
        /// <param name="nVehicles">Number of vehicles</param>
        /// <param name="rand">Random to use</param>
        private void CreateVehiclesAndSellers(VehicleCollection vhc, int nVehicles, Random rand) {
            for (int i = 0; i < nVehicles; i++) { // Create nVehicles vehicles
                int r = rand.Next(0, 5); // Determine which type of vehicle to create
                if (r == 0) {
                    vhc.AddVehicle(CreatePersonCar(rand));
                } else if (r == 1) {
                    vhc.AddVehicle(CreateTruck(rand));
                } else if (r == 2) {
                    vhc.AddVehicle(CreateVan(rand));
                } else if (r == 3) {
                    vhc.AddVehicle(CreateBus(rand));
                } else {
                    vhc.AddVehicle(CreateCamper(rand));
                }
            }
        }

        /// <summary>
        /// Creates a set of sellers
        /// </summary>
        /// <param name="vhc">VehicleCollection to add the sellers to</param>
        /// <param name="nSellers">Number of sellers to create</param>
        /// <param name="rand">Random to use</param>
        private void CreateSellers(VehicleCollection vhc, int nSellers, Random rand) {
            for (int i = 0; i < nSellers; i++) { // Create nSellers sellers
                vhc.Sellers.Add(new Seller(
                    SellerNames[rand.Next(0, SellerNames.Length)], // name
                    (rand.Next(1, 9) * 1000).ToString(), // zip
                    rand.Next(10000000, 100000000).ToString(), // phone
                    "http://google.com"));
            }
        }

        /// <summary>
        /// Creates a PersonCar instance
        /// </summary>
        /// <param name="rand">Random to use</param>
        /// <returns>A PersonCar instance</returns>
        private PersonCar CreatePersonCar(Random rand) {
            return new PersonCar(
                Brands[rand.Next(0, Brands.Length)], // brand
                Models[rand.Next(0, Models.Length)], // model
                rand.Next(0, 500001), // km
                new DateTime(rand.Next(1925, 2100), 1, 1), // year
                rand.Next(10000, 1000001), // price
                (double)(rand.Next(10, 43)) / 10, // motorsize
                (double)(rand.Next(50, 251)) / 10, // km/l
                (Fuel)(rand.Next(0, 3)) // fuel
                );
        }

        /// <summary>
        /// Creates a Truck instance
        /// </summary>
        /// <param name="rand">Random to use</param>
        /// <returns>A truck instance</returns>
        private Truck CreateTruck(Random rand) {
            return new Truck(
                Brands[rand.Next(0, Brands.Length)], // brand
                Models[rand.Next(0, Models.Length)], // model
                rand.Next(0, 1000001), // km
                new DateTime(rand.Next(1925, 2100), 1, 1), // year
                rand.Next(10000, 25000001), // price
                (double)(rand.Next(50, 151)) / 10, // motorsize
                (double)(rand.Next(50, 251)) / 10, // km/l
                Fuel.Diesel, // fuel
                rand.Next(1000, 20000 + 1), // loadcapaity
                TrueOrFalse[rand.Next(0, 2)], // bed
                (DriversLicense)rand.Next(2, 7), // license
                (double)(rand.Next(20, 46)) / 10, // height
                rand.Next(3000, 10000) // weight
                );
        }

        /// <summary>
        /// Creates a Van instance
        /// </summary>
        /// <param name="rand">Random to use</param>
        /// <returns>A Van Instance</returns>
        private Van CreateVan(Random rand) {
            return new Van(
                Brands[rand.Next(0, Brands.Length)], // brand
                Models[rand.Next(0, Models.Length)], // model
                rand.Next(0, 500001), // km
                new DateTime(rand.Next(1925, 2100), 1, 1), // year
                rand.Next(10000, 1000001), // price
                (double)(rand.Next(20, 42)) / 10, // motorsize
                (double)(rand.Next(50, 251)) / 10, // km/l
                (Fuel)(rand.Next(0, 3)), // fuel
                rand.Next(100, 5001), // LoadCapacity
                new Van.TrunkDimensions( // TrunkDimensions
                    (double)(rand.Next(10, 21) / 10), // Height
                    (double)(rand.Next(15, 21) / 10), // Width 
                    (double)(rand.Next(15, 41) / 10) // Length
                    )
                );
        }

        /// <summary>
        /// Creates a Bus instance
        /// </summary>
        /// <param name="rand">Random to use</param>
        /// <returns>A Bus instance</returns>
        private Bus CreateBus(Random rand) {
            return new Bus(
                Brands[rand.Next(0, Brands.Length)], // brand
                Models[rand.Next(0, Models.Length)], // model
                rand.Next(0, 500001), // km
                new DateTime(rand.Next(1925, 2100), 1, 1), // year
                rand.Next(10000, 1000001), // price
                (double)(rand.Next(42, 141)) / 10, // motorsize
                (double)(rand.Next(50, 251)) / 10, // km/l
                Fuel.Diesel, // fuel
                rand.Next(10, 101), // seats
                rand.Next(5, 51), // sleepseats
                TrueOrFalse[rand.Next(0, 2)], // toilet?
                (double)(rand.Next(25, 41)) / 10, // height
                rand.Next(2000, 5000) // weight
            );
        }

        /// <summary>
        /// Creates an Autocamper Instance
        /// </summary>
        /// <param name="rand">Random to use</param>
        /// <returns>An Autocamper instance</returns>
        private Autocamper CreateCamper(Random rand) {
            return new Autocamper(
                Brands[rand.Next(0, Brands.Length)], // brand
                Models[rand.Next(0, Models.Length)], // model
                rand.Next(0, 500001), // km
                new DateTime(rand.Next(1925, 2100), 1, 1), // year
                rand.Next(10000, 1000001), // price
                (double)(rand.Next(24, 61)) / 10, // motorsize
                (double)(rand.Next(50, 251)) / 10, // km/l
                (Fuel)(rand.Next(0, 3)), // fuel
                rand.Next(3, 13), // seats
                rand.Next(2, 6), // sleepseats
                (AutoCamperHeatingSystem)rand.Next(0, 3) // heating system
                );
        }
    }
}